package com.nexus.ai.gpt;

import com.nexus.ai.gpt.domain.NexusChatConfig;
import com.nexus.core.sys.entity.SysUser;
import com.nexus.core.utils.ObjectUtils;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SafeGuardAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.Prompt;

import java.util.Arrays;
import java.util.List;

/**
 * @Date 2025/9/27 19:04
 * @Author luzhengning
 **/
public abstract class BaseChatClient {
    /**
     * 大模型客户端
     *
     * @Date 2025/9/27 19:08
     * @Author luzhengning
     **/
    protected ChatClient chatClient;


    private ChatMemory chatMemory;

    private NexusChatConfig config;

    /**
     * 初始化大模型客户端
     * @Date 2025/9/27 21:56
     * @Author luzhengning
     **/
    public BaseChatClient(ChatClient.Builder chatClientBuilder, ChatMemory chatMemory) {
        //获取Chat配置
        NexusChatConfig config = initialChatConfig(new NexusChatConfig());
        //配置系统角色/人设
        if (ObjectUtils.isNotEmpty(config.getSystemMsg())) chatClientBuilder.defaultSystem(config.getSystemMsg());
        //其它配置
        if (ObjectUtils.isNotEmpty(config.getOptions())) chatClientBuilder.defaultOptions(config.getOptions());
        //此处可以进行模型切换：chatClientBuilder.build(OpenAiChatModel),chatClientBuilder.build(ZhipuAiChatModel);
        this.chatClient = chatClientBuilder.build();
        this.chatMemory = chatMemory;
        this.config = config;
    }

    /**
     * 初始化Chat配置
     * 子类重写
     *
     * @Date 2025/9/27 19:29
     * @Author luzhengning
     **/
    protected abstract NexusChatConfig initialChatConfig(NexusChatConfig chatConfig);


    /**
     * 提问消息
     * systemMsg:系统角色/人设，例如“我是智能客服”
     * msg:提问消息
     *
     * @Date 2025/9/27 17:08
     * @Author luzhengning
     **/
    public String chat(String msg) {
        String content = chatClient
                .prompt() //设置请求的上下文（如角色和内容）
                .user(msg)     //用户的输入消息
                .call()         //发送请求并获取模型生成的响应
                .content();     //从响应中获取文本内容
        return content;
    }

    /**
     * 自定义消息会话上下文存储
     * @Date 2025/9/27 23:46
     * @Author luzhengning
     **/
    public String chatSession(String sessionId,String msg) {
        //获取历史会话消息
        List<Message> historyMsgs = chatMemory.get(sessionId);
        //如果是首次会话，存储消息
        if(ObjectUtils.isEmpty(historyMsgs)){
            chatMemory.add(sessionId,new UserMessage(config.getSystemMsg()));
            //重新查询历史消息
            historyMsgs = chatMemory.get(sessionId);
        }
        //用户消息
        Message userMsg=new UserMessage(msg);
        //将本次消息合并到历史消息中
        historyMsgs.add(userMsg);
        //创建Prompt对象
        ChatClient.CallResponseSpec result = chat(historyMsgs);
        String content = result.content();
        //将响应添加至对话存储(助手角色)
        historyMsgs.add(new AssistantMessage(content));
        chatMemory.add(sessionId,historyMsgs);
        return result.content();
    }

    /**
     * 会话交由Advisor自动管理存储
     * @Date 2025/9/27 23:42
     * @Author luzhengning
     **/
    public String chatMessageAdvisor(String sessionId,String msg) {
        MessageChatMemoryAdvisor chatMemoryAdvisor= (MessageChatMemoryAdvisor) MessageChatMemoryAdvisor.builder(chatMemory).conversationId(sessionId).build();
        return chatClient.prompt().user(msg).advisors(chatMemoryAdvisor).call().content();
    }

    /**
     * 多轮对话优化
     * @Date 2025/9/27 23:52
     * @Author luzhengning
     **/
    public String chatPromptAdvisor(String sessionId,String msg) {
        PromptChatMemoryAdvisor chatMemoryAdvisor= (PromptChatMemoryAdvisor) PromptChatMemoryAdvisor.builder(chatMemory).conversationId(sessionId).build();
        return chatClient.prompt().user(msg).advisors(chatMemoryAdvisor).call().content();
    }

    /**
     * 对话安全测试
     * @Date 2025/9/28 00:03
     * @Author luzhengning
     **/
    public String chatSecurity(String sessionId,String msg) {

        //敏感词列表
        List<String> senstiveWords= Arrays.asList("色情","暴力","政治");
        //响应信息
        String failureResponse="无法回答此问题";
        //安全顾问组件
        SafeGuardAdvisor safeGuardAdvisor=SafeGuardAdvisor.builder().sensitiveWords(senstiveWords).failureResponse(failureResponse).order(0).build();
        return chatClient.prompt().user(msg).advisors(safeGuardAdvisor).call().content();
    }

    /**
     * 结构化输出
     *
     * @Date 2025/9/27 17:08
     * @Author luzhengning
     **/
    public SysUser chatEntity(String msg) { //介绍一下赵本山
        SysUser content = chatClient
                .prompt() //设置请求的上下文（如角色和内容）
                .user(msg)     //用户的输入消息
                .call()         //发送请求并获取模型生成的响应
                .entity(SysUser.class);     //从响应中获取JSON
        return content;
    }

    /**
     * 工具调用，或者在ChatClient.Builder中设置公共工具调用
     * @Date 2025/9/28 00:41
     * @Author luzhengning
     **/
    public SysUser chatTool(String msg) { //现在几点/获取指定地区的天气
        SysUser content = chatClient
                .prompt() //设置请求的上下文（如角色和内容）
                .user(msg)     //用户的输入消息
                //.tools(工具类，方法需要添加tool注解)
                .call()         //发送请求并获取模型生成的响应
                .entity(SysUser.class);     //从响应中获取JSON
        return content;
    }


    /**
     * 提问消息
     * systemMsg:系统角色/人设，例如“我是智能客服”
     * msg:用户消息，正式提问信息
     * temperature:多样化系数
     * maxTokens:限制token用量
     *
     * @Date 2025/9/27 17:18
     * @Author luzhengning
     **/
    public String chat(String systemMsg, String msg, Double temperature, int maxTokens) {
        ChatOptions options = ChatOptions.builder().temperature(temperature).maxTokens(maxTokens).build();
        ChatClient.CallResponseSpec chat = chat(new SystemMessage(systemMsg), null, new UserMessage(msg), options);
        return chat.content();
    }
    /**
     * 附加历史消息进行发问
     * @Date 2025/9/27 22:15
     * @Author luzhengning
     **/
    public ChatClient.CallResponseSpec chat(List<Message> historyList) {
        ChatClient.ChatClientRequestSpec requestSpec = chatClient.prompt(new Prompt(historyList));
        ChatClient.CallResponseSpec result = requestSpec.call();
        return result;
    }
    /**
     * 提问消息
     * systemMsg:系统角色/人设，例如“我是智能客服”
     * assistantHistory:助手角色
     * msg:用户消息，正式提问信息
     * options:模型参数
     *
     * @Date 2025/9/27 17:13
     * @Author luzhengning
     **/
    public ChatClient.CallResponseSpec chat(Message systemMsg, Message assistantHistory, Message msg, ChatOptions options) {
        Prompt prompt = new Prompt(List.of(systemMsg, assistantHistory, msg), options);
        ChatClient.ChatClientRequestSpec requestSpec = chatClient.prompt(prompt);
        ChatClient.CallResponseSpec result = requestSpec.call();
        return result;
    }





}
